
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


import java.awt.*;
import java.awt.event.ActionEvent;


//import com.googlecode.javacv.*;
//import com.googlecode.javacv.cpp.*;
import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
//import static com.googlecode.javacv.cpp.opencv_calib3d.*;
//import static com.googlecode.javacv.cpp.opencv_objdetect.*;
import static com.googlecode.javacv.cpp.opencv_highgui.*;


//import com.googlecode.javacv.cpp.opencv_core.CvArr;
import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
//import com.googlecode.javacv.cpp.opencv_imgproc.CvHistogram;


public class Histogram {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		IplImage image = cvLoadImage("1-1.jpg");
		histogram(image);
	}
	
	public static void histogram(IplImage image){
		int width = image.width();
	    int height = image.height();

		IplImage binary = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
		IplImage result = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
	    cvCvtColor(image, binary, CV_BGR2GRAY);
//	    CanvasFrame source = new CanvasFrame("Source");
	    CanvasFrame mod = new CanvasFrame("Modified");
//	    source.showImage(image);
//	    mod.showImage(binary);
	    
	    int[] hist = new int[256];
	    
	    for (int i = 0; i < height; i++)
	    {
	    	for (int j = 0; j < width; j++)
	    	{
	    		byte b = binary.imageData().get(i*width + j);
	    		if((int)b >= 0) //// no zero
	    		{
	    			hist[b]++;
	    		}
	    		else if((int)b < 0)// && (int)b > -128)/////
	    		{
	    			hist[256 + b]++;
	    		}
	    	}
	    }
	
	    int threshMean = adjustMean(hist, 128);
	    System.out.println(threshMean);
	    cvThreshold(binary, result, threshMean , 255, CV_THRESH_BINARY);
	    
	    mod.showImage(result);
	    
	}
	public static int adjustMean(int[] histogram, int mean)
	{
		int temp1 = 0;
		int temp2 = 0;
		int lessMean;
		int moreMean;
		
		for (int i = 0; i < mean; i++)
		{
			temp1 += histogram[i];
			temp2 += i * histogram[i];
		}
		lessMean = temp2 / temp1;
		
		for (int i = mean; i < 256; i++)
		{
			temp1 += histogram[i];
			temp2 += i * histogram[i];
		}
		moreMean = temp2 / temp1;
		
		int tempmean = (lessMean + moreMean) / 2;
		
		System.out.println("1");
		
		if(tempmean == mean)
		{
			printHist(histogram, mean);
			return mean;
		}
		else
			return adjustMean(histogram, tempmean);
	}
	public static void printHist(int[] hist, int mean)
	{
		CanvasFrame histogram = new CanvasFrame("histogram");
		IplImage can = cvCreateImage(cvSize(256,256), IPL_DEPTH_8U, 3);

		int max = 256* 200;	
		double scale = max > can.height() ? (double)can.height()/max : 1.;
		
		for (int i = 0; i < 256; i++)
		{
			CvPoint pt1 = cvPoint(i, (int) (can.height() - (hist[i] * scale)));
			CvPoint pt2 = cvPoint(i, can.height());
			cvLine(can, pt1, pt2, CV_RGB(255,255,255), 1, 8, 0);
		}
		CvPoint pt1 = cvPoint(mean, 0);
		CvPoint pt2 = cvPoint(mean, can.height());
		cvLine(can, pt1, pt2, CV_RGB(255,0,0), 1, 8, 0);
		histogram.showImage(can);
	}

}

